vscode github 图床插件 markdown-pic2github 改造

支持图床服务的编辑器

目前市场上的图床服务还是比较多的, 比如 githubimgursm.ms七牛云存储upyun存储阿里oss云存储腾讯oss云存储weibo 等.选择哪种图床服务取决于个人喜好, 重要的是这些图床服务得有一个比较好的类似图形化的工具, 方便使用者.这就得看使用的 markdown 编辑器是否支持这样的功能.个人使用的是 github 图床服务.

小书匠

目前在这方便做的比较好的是 小书匠.提供了多种图床服务, 支持一些自定义的命名规则.功能按钮就能直接上传图片到指定的图床服务, 并返回对应的图片链接.不过 小书匠 还是有一些不尽人意的地方, 所以最终没有使用.

GitNode

这是一款最近才出来的编辑器, 也提供了一些图床服务(以插件的方式提供), 不过目前做的比较简单, 另外扩展 API 还不完善, 持续观望中.

vscode

vscode 是一款扩展能力很强的编辑器, 可通过编写插件来进行扩展.目前也是支持了一些图传的服务.而支持 github 图床的, 目前只找到了 markdown-pic2github 这一个.下面会分析这款插件有哪些方面的不足, 以及如何进行改进.

插件地址: https://marketplace.visualstudio.com/items?itemName=quareia.markdown-pic2github
github 地址: https://github.com/Quareia/vscode-markdown-pic2github

markdown-pic2github 的不足以及改造点

首先先分析下此插件有哪些方便的不足, 以及如何进行改造来满足自定义的需求.

  • windows 环境下无法使用, 主要有几下几个原因导致:
    • 不支持 cp 命令, 复制文件.需要使用 copy 或者 xcopy 命令复制文件
    • 进入系统盘外的磁盘目录, 只通过 cd 命令还不够.比如, 进入 E:\git 目录, 使用 cmd 需要两条命令(E: && cd E:\git)才能进入,
  • 没有对图片 url 进行转义, 这会导致如果 url 有特殊字符, 那么会导致返回的图片 url 有问题.
  • 没有足够好的目录归档支持, 比如有一个 hello.md 文档, 文档里有多张图片, 那么这些图片最好能够归档到 hello 这一个目录下, 便于进行管理.对于这一点, 自己使用了如下的方式进行管理.比如在某个 git 服务(github、gitee 等)上创建了一个 blog 仓库用于存放自己的笔记信息(可能是私有的, 毕竟不是所有的笔记文档都想公开).并在 github 上建立了一个 public 仓库来存放图片相关的文件, 比如叫 blog-files.下面我们创建了一个 hello.md 的文档, 在 blog 仓库的位置如下:
1
2
3
4
5
blog
|Java
| 基础知识
| hello.md
| JavaScript

此文档上传了两张图片(Figure-1 hello.pngFigure-2 world.png), 那么我希望在 blog-files 仓库这张图片的存放位置可以如下:

1
2
3
4
5
6
7
blog-files
|images
|Java
|基础知识
|hello
|Figure-1 hello.png
|Figure-2 world.png

markdown-pic2github 改造

找到此插件的目录, 对 extension.js 的源码进行修改.虽然不熟悉 js, nodejs 等相关技术, 不过依葫芦画瓢, 先试试再说, 核心代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 解构
let {fsPath} = result[0]
let imgName = fsPath.split(path.sep).pop()
let cmdStr = 'cp ' + fsPath + ' ' + localFolder + ' && ' +
'cd ' + localFolder + ' && ' +
'git add ' + imgName + ' && ' +
'git commit -m ' + doc.fileName.split(path.sep).pop() + ' && ' +
'git push'
console.log(cmdStr)
exec(cmdStr, function(err, stdout, stderr) {
if (err) {
console.log('wrong:' + stderr)
} else {
let data = stdout
console.log(data)
}
})
let imgUrl = '![](https://raw.githubusercontent.com/' + remoteRepo +'/master/'+ imgName + ')'
editor.edit(textEditorEdit => {
textEditorEdit.insert(editor.selection.active, imgUrl)
})

从上面可以看到其实不是很难嘛, 都是一些比较简单的语法还有 API 的使用.另外可以看到其实插件最终是拼接了一条命令字符串, 然后应该是让操作系统执行.最终将图片的地址拼接出来插入到文档中.按照上面的要求, 做了如下的几点修改:

  • 命令字符串中使用的是 cp 命令, 这在 windows 上是没法使用的, 所以我们需要改成 xcopy 命令, 为了防止图片有空格, 最好在在命令中的图片名称前后加上 ".另外为了覆盖当前已存在的文件, 在此命令最后加上 /y 参数.
  • doc.fileName(vscode.window.activeTextEditor.document.fileName) 取得是当前编辑文档的全路径.通过这个全路径我们可以知道是在哪个磁盘目录, 由此可以进入到 git 的根目录.根据这个根目录和文档的全路径, 可以得到要创建的图片的目录.比如, 当前编辑的 hello.md 文档位于 E:\git\blog\Java\基础知识\hello.md, 则在 E:\git\blog-files\images 目录下创建 Java\基础知识\hello 目录.
  • 创建目录使用 mkdir 命令, 如果创建的目录存在的话会报错, 所以我们需要先进行判断, 不存在则创建, 所以需要使用命令: if not exists Java\基础知识\hello mdir Java\基础知识\hello, 另外, 因为后面还要拼接 git 相关的命令, 所以讲这条命令放在 () 中, 防止发生短路与, 导致后面的命令不执行.

经过上面的改造, 我们可以得出类似于下面的命令:

1
E: && cd E:\git\blog-files\images && (if not exists Java\基础知识\hello mdir Java\基础知识\hello) && xcopy "E:\temp\images\Figure-1 hello.png" "E:\git\blog-files\images\Java\基础知识\hello\Figure-1 hello.png" /y && git add "images\Java\基础知识\hello\Figure-1 hello.png" && git commit -m "hello.md" && git push

通过上面一系列命令的组合, 我们就完成了我们想要的整个功能.其实改造的成本并不大, 而且没太多的难度.详细代码可见 https://github.com/ykgarfield/vscode-markdown-pic2github, 如果有自己的特殊要求, 完全可以自行改造.

从 fesacr 源码中总结出的 Java 代码编写注意事项
第3章-微服务架构中的进程间通信